package main

import (
	"encoding/json"
	"fmt"
	"net"
	"os"
	"strings"
	"time"
)

// DeviceInfo 包含设备信息
type DeviceInfo struct {
	MACAddress   string `json:"mac_address"`
	SerialNumber string `json:"serial_number"`
	IPAddress    string `json:"ip_address"`
	Netmask     string `json:"netmask"`
	Gateway     string `json:"gateway"`
}

func main() {
	// 启动接收协程
	go receiveMulticast()

	// 获取本机MAC地址
	interfaces, err := net.Interfaces()
	if err != nil {
		fmt.Println("获取网络接口失败:", err)
		return
	}

	var macAddr string
	for _, iface := range interfaces {
		// 根据接口名称筛选(这里假设LAN1接口名为"eth0"或"以太网")
		if strings.Contains(strings.ToLower(iface.Name), "eth0") || 
		   strings.Contains(strings.ToLower(iface.Name), "以太网") ||
		   strings.Contains(strings.ToLower(iface.Name), "lan1") {
			if iface.HardwareAddr != nil {
				macAddr = iface.HardwareAddr.String()
				break
			}
		}
	}

	if macAddr == "" {
		fmt.Println("无法获取LAN1的MAC地址")
		return
	}

	// 获取设备序列号(从/etc/device_info文件读取)
	serialNumber := "unknown"
	content, err := os.ReadFile("/etc/device_info")
	if err == nil {
		// 假设文件内容是简单的key=value格式，如：SN=ABCD1234
		lines := strings.Split(string(content), "\n")
		for _, line := range lines {
			if strings.HasPrefix(line, "SN=") {
				serialNumber = strings.TrimSpace(strings.TrimPrefix(line, "SN="))
				break
			}
		}
	} else {
		fmt.Printf("读取设备信息文件失败: %v, 使用默认值\n", err)
	}

	// 准备设备信息
	device := DeviceInfo{
		MACAddress:   macAddr,
		SerialNumber: serialNumber,
		IPAddress:    getLocalIP(macAddr), // 新增获取IP地址函数
		Netmask:     "255.255.255.0",     // 示例子网掩码
		Gateway:     "192.168.1.1",       // 示例网关
	}

	// 组播地址和端口
	multicastAddr := "224.0.0.1:9999"

	// 解析组播地址
	addr, err := net.ResolveUDPAddr("udp", multicastAddr)
	if err != nil {
		fmt.Println("解析组播地址失败:", err)
		return
	}

	// 获取LAN1接口
	var lanInterface *net.Interface
	for _, iface := range interfaces {
		if strings.Contains(strings.ToLower(iface.Name), "eth0") || 
		   strings.Contains(strings.ToLower(iface.Name), "以太网") ||
		   strings.Contains(strings.ToLower(iface.Name), "lan1") {
			lanInterface = &iface
			break
		}
	}

	if lanInterface == nil {
		fmt.Println("无法找到LAN1接口")
		return
	}

	// 创建UDP连接并绑定到LAN1接口
	conn, err := net.DialUDP("udp", nil, addr)
	if err != nil {
		fmt.Println("创建UDP连接失败:", err)
		return
	}
	defer conn.Close()

	// 设置发送接口
	if err := conn.SetWriteBuffer(8192); err != nil {
		fmt.Println("设置发送缓冲区失败:", err)
	}
	if err := conn.SetMulticastInterface(lanInterface); err != nil {
		fmt.Println("设置组播接口失败:", err)
	}

	// 序列化设备信息为JSON
	deviceJSON, err := json.Marshal(device)
	if err != nil {
		fmt.Println("JSON序列化失败:", err)
		return
	}

	// 发送设备信息
	_, err = conn.Write(deviceJSON)
	if err != nil {
		fmt.Println("发送数据失败:", err)
		return
	}

	fmt.Printf("已发送设备信息: MAC=%s, SN=%s\n", device.MACAddress, device.SerialNumber)

	// 保持程序运行以接收消息
	select {}
}

// 接收组播消息
// 新增netplan配置结构
type NetplanConfig struct {
    Network struct {
        Version  int `yaml:"version"`
        Renderer string `yaml:"renderer"`
        Ethernet map[string]interface{} `yaml:"ethernets"`
    } `yaml:"network"`
}

// 新增使用netplan配置IP的函数
func configureIPWithNetplan(interfaceName, ip, netmask, gateway string) error {
    config := NetplanConfig{}
    config.Network.Version = 2
    config.Network.Renderer = "networkd"
    config.Network.Ethernet = make(map[string]interface{})
    
    config.Network.Ethernet[interfaceName] = map[string]interface{}{
        "dhcp4": false,
        "addresses": []string{ip + "/" + netmaskToCIDR(netmask)},
        "gateway4": gateway,
        "nameservers": map[string][]string{
            "addresses": {"8.8.8.8", "8.8.4.4"},
        },
    }

    // 生成YAML内容
    yamlData, err := yaml.Marshal(&config)
    if err != nil {
        return fmt.Errorf("生成YAML失败: %v", err)
    }

    // 写入配置文件
    configPath := "/etc/netplan/99-custom-config.yaml"
    err = os.WriteFile(configPath, yamlData, 0644)
    if err != nil {
        return fmt.Errorf("写入配置文件失败: %v", err)
    }

    // 应用配置
    cmd := exec.Command("netplan", "apply")
    if err := cmd.Run(); err != nil {
        return fmt.Errorf("应用netplan配置失败: %v", err)
    }

    return nil
}

// 子网掩码转CIDR
func netmaskToCIDR(netmask string) string {
    ip := net.ParseIP(netmask)
    if ip == nil {
        return "24" // 默认/24
    }
    ones, _ := net.IPMask(ip.To4()).Size()
    return fmt.Sprintf("%d", ones)
}

// 在接收函数中添加netplan配置
func receiveMulticast() {
	multicastAddr := "224.0.0.1:9999"
	addr, err := net.ResolveUDPAddr("udp", multicastAddr)
	if err != nil {
		fmt.Println("接收端解析组播地址失败:", err)
		return
	}

	conn, err := net.ListenMulticastUDP("udp", nil, addr)
	if err != nil {
		fmt.Println("创建接收连接失败:", err)
		return
	}
	defer conn.Close()

	conn.SetReadDeadline(time.Now().Add(24 * time.Hour))

	fmt.Println("开始监听组播消息...")
	for {
		buf := make([]byte, 1024)
		n, _, err := conn.ReadFromUDP(buf)
		if err != nil {
			fmt.Println("接收数据失败:", err)
			continue
		}

		var device DeviceInfo
		if err := json.Unmarshal(buf[:n], &device); err != nil {
			fmt.Println("解析接收数据失败:", err)
			continue
		}

		// 配置网络
		if err := configureIPWithNetplan("eth0", device.IPAddress, device.Netmask, device.Gateway); err != nil {
			fmt.Printf("配置网络失败: %v\n", err)
		} else {
			fmt.Printf("成功配置网络: IP=%s\n", device.IPAddress)
		}

		fmt.Printf("收到设备信息: MAC=%s, SN=%s\n", device.MACAddress, device.SerialNumber)
	}
}

// 获取本地IP地址
func getLocalIP(macAddr string) string {
	interfaces, err := net.Interfaces()
	if err != nil {
		return "unknown"
	}

	for _, iface := range interfaces {
		if iface.HardwareAddr != nil && iface.HardwareAddr.String() == macAddr {
			addrs, err := iface.Addrs()
			if err != nil || len(addrs) == 0 {
				return "unknown"
			}
			// 获取第一个非回环的IPv4地址
			for _, addr := range addrs {
				if ipnet, ok := addr.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
					if ipnet.IP.To4() != nil {
						return ipnet.IP.String()
					}
				}
			}
		}
	}
	return "unknown"
}